Java JavaScript Python C# C C++ Go Kotlin PHP Swift R Ruby TypeScript Scala SQL Perl rust VisualBasic Matlab Julia

Encapsulation → Access Modifiers

Encapsulation

Access Modifiers

Access Modifiers in Python: Public, Private, and Protected

While Python doesn't enforce access modifiers (public, private, protected) as strictly as languages like Java or C++, it employs naming conventions to signal intended access levels. This helps developers structure their code for better organization, maintainability, and encapsulation. Let's explore these conventions with examples:

1. Public Members

Public members are accessible from anywhere – inside or outside the class. No special syntax is needed to declare a public member; it's the default.
Access Modifier in Python - public member example class Dog: def __init__(self, name, breed): self.name = name # Public attribute self.breed = breed # Public attribute def bark(self): # Public method print("Woof!") my_dog = Dog("Buddy", "Golden Retriever") print(my_dog.name) # Accessing public attribute my_dog.bark() # Calling public method

Output

Buddy Woof!

2. Protected Members

Protected members are intended for internal use within the class and its subclasses. The convention is to prefix the member name with a single underscore (`_`). This signals to other developers that the member shouldn't be accessed directly from outside the class, although technically it's still accessible.
Access Modifier in Python - protected member example class Cat: def __init__(self, name, age): self._name = name # Protected attribute self._age = age # Protected attribute def get_name(self): # Public method to access protected attribute return self._name def _private_helper(self): # Protected method (internal helper) print("This is an internal helper method.") my_cat = Cat("Whiskers", 3) print(my_cat._name) # Accessing protected attribute (though discouraged) my_cat._private_helper() #Calling protected method (though discouraged) print(my_cat.get_name()) # Preferred way to access protected attribute class Kitten(Cat): def __init__(self, name, age, color): super().__init__(name, age) self.color = color def display_info(self): print(f"Kitten Name: {self._name}, Age: {self._age}, Color: {self.color}") my_kitten = Kitten("Snowball", 1, "White") my_kitten.display_info() #Subclasses can access protected members

Output

Whiskers This is an internal helper method. Whiskers Kitten Name: Snowball, Age: 1, Color: White
Accessing protected members directly from outside the class is generally discouraged because it breaks the intended encapsulation and can lead to unexpected behavior if the internal implementation changes. Subclasses are an exception; they can access and utilize protected members for inheritance purposes.

3. Private Members

Private members are intended to be strictly internal to the class; they are not supposed to be accessed from outside the class or even by its subclasses. The convention is to prefix the member name with two underscores (`__`). Python uses name mangling to make it harder (but not impossible) to access these members directly.
Access Modifier in Python - private member example class Bird: def __init__(self, species): self.__species = species # Private attribute self.__wingspan = 2.0 #private attribute def get_species(self): return self.__species my_bird = Bird("Eagle") #print(my_bird.__species) # This will raise an AttributeError #Name Mangling, this will work but discouraged print(my_bird._Bird__species) #Accessing through public methods print(my_bird.get_species())

Output

Eagle Eagle
Python's name mangling transforms `__species` into `_Bird__species`. While this makes direct access more difficult, it's not truly impossible. The main benefit of private members is to explicitly signal the intent that these attributes are truly internal implementation details. They should not be relied upon by external code.
In Summary ⮚ Python's access modifiers are based on naming conventions, not strict enforcement. ⮚ Public members are freely accessible. ⮚ Protected members are intended for internal use within the class and its subclasses, signaled by a single underscore. ⮚ Private members are intended for strictly internal use within the class, signaled by a double underscore; Python uses name mangling to make direct access harder. While Python doesn't enforce the restrictions as rigidly as other languages, adhering to these conventions significantly improves code readability, maintainability, and reduces the likelihood of accidental breakage when the internal implementation of a class is modified. The key is communicating intent clearly through naming; good programmers respect this convention even though Python doesn't strictly mandate it.

Tutorials